package com.tanhua.dubbo.server.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.tanhua.dubbo.server.pojo.UserLike;
import com.tanhua.dubbo.server.vo.PageInfo;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service(version = "1.0.0")
public class MyCenterApiImpl implements MyCenterApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public static final String LIKE_REDIS_KEY_PREFIX = "USER_LIKE_";

    public static final String FAN_REDIS_KEY_PREFIX = "USER_FANS_";

    /**
     * 查询互相喜欢数
     *
     * @param uid
     * @return
     */
    @Override
    public Long queryEachLoveCount(Long uid) {
        //获取用户的喜欢列表
        List<Long> userLikeList = queryUserLike(uid);
        //定义互相喜欢数初始为0
        Long count = 0L;
        for (Long userLikeId : userLikeList) {
            //查看我喜欢的用户是否也喜欢我
            if (queryUesrIsLike(uid, userLikeId)) {
                //表示是互相喜欢
                count++;
            }
        }
        return count;
    }

    /**
     * 查询我的喜欢数
     *
     * @param uid
     * @return
     */
    @Override
    public Long queryLoveCount(Long uid) {
        List<Long> userLikeList = queryUserLike(uid);
        return Convert.toLong(userLikeList.size());
    }

    /**
     * 查询我的粉丝数
     *
     * @param uid
     * @return
     */
    @Override
    public Long queryFanCount(Long uid) {
        //先去redis中查询我的粉丝数
        String redisKey = getFanRedisKeyPrefix(uid);
        String data = redisTemplate.opsForValue().get(redisKey);
        if (StrUtil.isNotEmpty(data)) {
            //redis中有数据
            return Convert.toLong(data);
        }
        //redis中没有数据,到数据库中查询
        Query query = Query.query(Criteria.where("likeUserId").is(uid));
        long count = mongoTemplate.count(query, UserLike.class);
        //将结果存放到redis中
        redisTemplate.opsForValue().set(redisKey, count + "", 24, TimeUnit.HOURS);
        return count;
    }

    /**
     * 查询互相喜欢的用户列表
     *
     * @param page
     * @param pagesize
     * @return
     */
    @Override
    public PageInfo<Long> queryEachLoveList(Long uid, Integer page, Integer pagesize) {
        PageInfo<Long> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pagesize);
        //获取我喜欢的所有用户id

        List<Long> likeList = queryUserLikeByPage(uid, page, pagesize);
        if (ObjectUtil.isEmpty(likeList)) {
            //表示我没有喜欢的用户,也就没有互相关注的用户
            return pageInfo;
        }

        List<Long> likeMeList = new ArrayList<>();
        for (Long likeUserId : likeList) {
            //查询该用户是否喜欢我
            if (queryUesrIsLike(uid, likeUserId)) {
                //表示该用户也喜欢我,记录该Id
                likeMeList.add(likeUserId);
            }
        }
        if (ObjectUtil.isEmpty(likeMeList)) {
            //表示没有用户喜欢我
            return pageInfo;
        }
        //likeMeList里存储着互相喜欢的用户id
        pageInfo.setRecords(likeMeList);
        return pageInfo;
    }

    /**
     * 查询我的关注用户列表
     *
     * @param page
     * @param pagesize
     * @return
     */
    @Override
    public PageInfo<Long> queryLoveList(Long uid, Integer page, Integer pagesize) {
        PageInfo<Long> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pagesize);

        pageInfo.setRecords(queryUserLikeByPage(uid, page, pagesize));
        return pageInfo;
    }

    /**
     * 查询我的粉丝用户列表
     *
     * @param page
     * @param pagesize
     * @return
     */
    @Override
    public PageInfo<Long> queryFanList(Long uid, Integer page, Integer pagesize) {
        PageInfo<Long> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pagesize);

        PageRequest pageRequest = PageRequest.of(Math.max(1, page) - 1, pagesize);
        Query query = new Query(Criteria.where("likeUserId").is(uid)).with(pageRequest);
        List<UserLike> userLikeList = mongoTemplate.find(query, UserLike.class);
        List<Object> list = CollUtil.getFieldValues(userLikeList, "userId");
        List<Long> userFansId = new ArrayList<>();
        for (Object l : list) {
            userFansId.add(Convert.toLong(l));
        }
        pageInfo.setRecords(userFansId);
        return pageInfo;
    }

    /**
     * 查询我的访客列表
     *
     * @param uid
     * @param page
     * @param pagesize
     * @return
     */
    @Override
    public PageInfo<Long> queryVisitorList(Long uid, Integer page, Integer pagesize) {
        return null;
    }

    /**
     * 获取用户所有已喜欢的用户id
     *
     * @param uid
     * @return
     */
    public List<Long> queryUserLike(Long uid) {
        //查询缓存中是否有数据
        String redisKey = getLikeRedisKeyPrefix(uid);
        Set<Object> keys = redisTemplate.opsForHash().keys(redisKey);
        List<Long> longList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(keys)) {
            //表示缓存中存有用户喜欢的id
            for (Object key : keys) {
                longList.add(Convert.toLong(key));
            }
            return longList;
        }
        //表示缓存中没有数据,到数据库中再次查询
        Query query = Query.query(Criteria.where("userId").is(uid));
        List<UserLike> userLikeList = mongoTemplate.find(query, UserLike.class);
        if (ObjectUtil.isNotEmpty(userLikeList)) {
            //表示数据库中存有数据
            List<Object> likeUserIds = CollUtil.getFieldValues(userLikeList, "likeUserId");
            for (Object likeUserId : likeUserIds) {
                longList.add(Convert.toLong(likeUserId));
                //同步存入到缓存中
                redisTemplate.opsForHash().put(redisKey, likeUserId.toString(), "1");
            }
        }
        //表示没有喜欢的用户id
        return longList;
    }

    private List<Long> queryUserLikeByPage(Long uid, Integer page, Integer pagesize) {
        List<Long> longList = new ArrayList<>();
        //表示缓存中没有数据,到数据库中再次查询
        PageRequest pageRequest = PageRequest.of(Math.max(1, page) - 1, pagesize);
        Query query = Query.query(Criteria.where("userId").is(uid)).with(pageRequest);
        List<UserLike> userLikeList = mongoTemplate.find(query, UserLike.class);
        if (ObjectUtil.isNotEmpty(userLikeList)) {
            //表示数据库中存有数据
            List<Object> likeUserIds = CollUtil.getFieldValues(userLikeList, "likeUserId");
            for (Object likeUserId : likeUserIds) {
                longList.add(Convert.toLong(likeUserId));
            }
        }
        //表示没有喜欢的用户id
        return longList;
    }

    /**
     * 粉丝 - 喜欢
     *
     * @param uid
     * @param fansId
     * @return
     */
    @Override
    public Boolean likeFans(Long uid, Long fansId) {
        try {
            if (queryUesrIsLike(fansId, uid)) {
                //表示已经喜欢,无需再喜欢
                return false;
            }
            //表示还未喜欢,进行喜欢操作
            UserLike userLike = new UserLike();
            userLike.setId(ObjectId.get());
            userLike.setUserId(uid);
            userLike.setLikeUserId(fansId);
            userLike.setCreated(System.currentTimeMillis());
            mongoTemplate.save(userLike);
            //保存到缓存中
            String redisKey = getLikeRedisKeyPrefix(uid);
            redisTemplate.opsForHash().put(redisKey, fansId + "", "1");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 喜欢 - 取消
     *
     * @return
     */
    @Override
    public Boolean unLike(Long uid, Long fansId) {
        try {
            if (!queryUesrIsLike(fansId, uid)) {
                //表示是不喜欢,无需取消喜欢
                return false;
            }
            //表示是喜欢,进行取消喜欢操作,先删除缓存中的数据
            String redisKey = getLikeRedisKeyPrefix(uid);
            redisTemplate.opsForHash().delete(redisKey,fansId+"");
            //删除数据库中的数据
            Query query =Query.query(Criteria.where("userId").is(uid).and("likeUserId").is(fansId));
            mongoTemplate.remove(query,UserLike.class);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 查询我是否喜欢ta
     *
     * @param likeUserId 喜欢的用户id
     * @param userId     我的id
     * @return
     */
    @Override
    public Boolean queryUesrIsLike(Long likeUserId, Long userId) {
        //先在缓存中查询
        String redisKey = getLikeRedisKeyPrefix(userId);
        Object data = redisTemplate.opsForHash().get(redisKey, likeUserId + "");
        if (ObjectUtil.isNotEmpty(data)) {
            //缓存有数据,表示已经喜欢
            return true;
        }
        //缓存中没有数据,去数据库中查找
        Query query = Query.query(Criteria.where("userId").is(userId).and("likeUserId").is(likeUserId));
        long count = mongoTemplate.count(query, UserLike.class);
        if (count > 0) {
            //表示数据库有数据
            return true;
        }
        //表示数据库也没有数据
        return false;

    }

    private String getLikeRedisKeyPrefix(Long uid) {
        return LIKE_REDIS_KEY_PREFIX + uid;
    }

    //获取redis中粉丝总数 key
    private String getFanRedisKeyPrefix(Long uid) {
        return FAN_REDIS_KEY_PREFIX + uid;
    }
}
